﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Input;

namespace EnsureWeb.Share
{
    public static class DragHelper
    {
        public static void Drag(this FrameworkElement attachedElement)
        {
            bool isDragging = false;
            Point lastPosition = new Point(0, 0);

            attachedElement.MouseLeftButtonDown += (s, e) =>
            {
                isDragging = true;
                lastPosition = e.GetPosition(null);
                attachedElement.CaptureMouse();
            };

            attachedElement.MouseLeftButtonUp += (s, e) =>
            {
                isDragging = false;
                attachedElement.ReleaseMouseCapture();
            };

            attachedElement.MouseMove += (s, e) =>
            {
                if (!isDragging)
                    return;

                Point currentPosition = e.GetPosition(null);

                double dX = currentPosition.X - lastPosition.X;
                double dY = currentPosition.Y - lastPosition.Y;

                lastPosition = currentPosition;

                Transform oldTransform = attachedElement.RenderTransform;
                TransformGroup rt = new TransformGroup();
                TranslateTransform newPos = new TranslateTransform();
                newPos.X = dX;
                newPos.Y = dY;

                if (oldTransform != null)
                {
                    rt.Children.Add(oldTransform);
                }
                rt.Children.Add(newPos);

                MatrixTransform mt = new MatrixTransform();
                mt.Matrix = rt.Value;

                attachedElement.RenderTransform = mt;

            };
        }

        public static void Drag(this FrameworkElement attachedElement, object dragObject)
        {
            attachedElement.Drag(dragObject, null, null);
        }

        public static void Drag(this FrameworkElement attachedElement, object dragObject, MouseEventHandler onMove, MouseButtonEventHandler onDragCompleted)
        {
            Popup rootPopup = new Popup();
            rootPopup.IsOpen = false;

            ContentControl dragElement = new ContentControl();
            dragElement.Content = dragObject;

            rootPopup.Child = dragElement;

            bool isDragging = false;
            Point lastPosition = new Point(0, 0);

            attachedElement.MouseLeftButtonDown += (s, e) =>
            {
                isDragging = true;
                lastPosition = e.GetPosition(null);
                dragElement.CaptureMouse();

                Point p = e.GetPosition(attachedElement);
                rootPopup.IsOpen = true;
                rootPopup.HorizontalOffset = lastPosition.X - p.X;
                rootPopup.VerticalOffset = lastPosition.Y - p.Y;
            };

            dragElement.MouseLeftButtonUp += (s, e) =>
            {
                isDragging = false;
                dragElement.ReleaseMouseCapture();

                rootPopup.IsOpen = false;
                dragElement.RenderTransform = null;

                if (onDragCompleted != null)
                    onDragCompleted(s, e);
            };

            dragElement.MouseMove += (s, e) =>
            {
                if (!isDragging)
                    return;

                Point currentPosition = e.GetPosition(null);

                double dX = currentPosition.X - lastPosition.X;
                double dY = currentPosition.Y - lastPosition.Y;

                lastPosition = currentPosition;

                Transform oldTransform = dragElement.RenderTransform;
                TransformGroup rt = new TransformGroup();
                TranslateTransform newPos = new TranslateTransform();
                newPos.X = dX;
                newPos.Y = dY;

                if (oldTransform != null)
                {
                    rt.Children.Add(oldTransform);
                }
                rt.Children.Add(newPos);

                MatrixTransform mt = new MatrixTransform();
                mt.Matrix = rt.Value;

                dragElement.RenderTransform = mt;

                if (onMove != null)
                    onMove(s, e);
            };
        }
    }
}
